package com.qianfeng.springcloud.gateway.config;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qianfeng.springcloud.gateway.filters.MyGatewayFilter;
import com.qianfeng.springcloud.gateway.pojo.DiZhi;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * Created by Jackiechan on 2022/7/11 15:11
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Configuration
public class GateWayBodyConfig {

    private MyGatewayFilter myGatewayFilter;

    @Autowired
    public void setMyGatewayFilter(MyGatewayFilter myGatewayFilter) {
        this.myGatewayFilter = myGatewayFilter;
    }

    private ObjectMapper objectMapper;

    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    /**
     * 就是用代码来配置我们的路由的规则,比如断言,过滤器啊等等,有些过滤器必须使用代码来进行设置
     *
     * @return
     */
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()//配置路由
                //参数1,id. 参数2,断言
                .route("suibianxiegeid",//配置每个路由的相关设置
                        r -> r.path("/address/**")
                                //当前的过滤器主要是用户传递的数据和我们下游期望要的结果不一致,我们需要进行转换,具体如何转换取决于业务,可能是类型的变化,可能是内容的变化
                                //参数1 用户传递的数据类型,参数2 我们要转发出去的数据类型
                                //参数3 出去的数据的格式是什么
                                //参数4 如何将传入的数据转成传出的数据
                                .filters(f -> f.modifyRequestBody(String.class, DiZhi.class, MediaType.APPLICATION_JSON_VALUE,
                                        //s就是收到的数据
                                        (exchange, s) -> {
                                            try {
                                                //将数据从json字符串转过来
                                                return Mono.just(objectMapper.readValue(s, DiZhi.class));
                                            } catch (JsonProcessingException e) {
                                                e.printStackTrace();
                                            }
                                            return Mono.empty();
                                        })  //如果我们要返回的数据内容的mime-type和原始的不一样,需要通过setResponseHeader进行修改
                                        .setResponseHeader(HttpHeaders.CONTENT_TYPE,MediaType.TEXT_HTML_VALUE)
                                        //参数1 服务返回的数据类型
                                        //参数2 我们期望给用户的数据类型
                                        //参数3 content-type
                                        //参数4 如何转换
                                        .modifyResponseBody(DiZhi.class,String.class,MediaType.TEXT_HTML_VALUE,(exchange, dizhi)->{
                                    try {
                                        //我们是通过将数据转成字符串返回
                                        return Mono.just(objectMapper.writeValueAsString(dizhi));
                                    } catch (JsonProcessingException e) {
//                                        throw new RuntimeException(e);
                                        e.printStackTrace();
                                    }
                                    //如果出现异常,返回一个空数据,实际取决于业务
                                    return Mono.empty();
                                })          //使用自定义过滤器
                                                .filter(myGatewayFilter.apply(new MyGatewayFilter.Config("测试的名字",189)))
                                ).uri("lb://10addressproviderhystrix"))//设置地址
                .build();
    }
}
